<?php
/**
 * This file is part of the Agora distribution. 
 * Detailed copyright and licensing information can be found
 * in the gpl-3.0.txt file which should be included in the distribution.
 * 
 * @version		$Id: 3.0.14 Olympus 2010-09-28 rammstein4o $
 * @copyright  2007 - 2010 jVitals
 * @license   GPLv3 Open Source
 * @link       http://jvitals.com
 * @since      File available since initial release
 */
	defined('IN_AGORA') or die;
	
	// nasty
	@define ('AGORA_PATH', JPATH_ROOT . DS . 'components' . DS . 'com_agora' . DS);
	@define ('AGORA_CURRENT_PATH', JPATH_BASE . DS . 'components' . DS . 'com_agora' . DS);
	if (!function_exists('ainclude')) require_once AGORA_PATH . 'include' . DS . 'utils.php';
	if (!class_exists('Model')) ainclude('model|model');
	if (!class_exists('Agora')) ainclude('include|agora.j15');

	class AgoraDispatcher
	{
		static $slugRegex = '/^([0-9]+)(?:[\-\:][A-Z0-9\-]*)?$/Di';
		
		function AgoraDispatcher()
		{
			$this->__construct();
		}

		function __construct()
		{
			$this->_vars['task'] = 'index';
			$this->_vars['page'] = null;
			$this->_vars['action'] = null;
			
			$cfg = Agora::config();
			if (@$cfg['router_slugs']) {
				$this->_vars['id'] = null;
			}
		}

		function & getInstance()
		{
			static $inst;

			if (!isset($inst)) {
				$inst = new AgoraDispatcher();
			}
			
			return $inst;
		}

		function getVar($var)
		{
			return isset($this->_vars[$var]) ? $this->_vars[$var] : null;
		}

		function setVar($var,$value)
		{
			$this->_vars[$var] = $value;
			if (!isset($_GET[$var]) || !strlen(trim($_GET[$var]))) {
				$_GET[$var] = $value;
			}
			if (!isset($_REQUEST[$var]) || !strlen(trim($_REQUEST[$var]))) {
				$_REQUEST[$var] = $value;
			}
		}

		function loadController($fs_path,& $path)
		{
/*			if (count($path) === 0) {
				die('Bad request (code 1002)');
			}*/

			if (count($path) > 0) {
				$task = array_shift($path);
			} else {
				$task = 'index';
			}

			if (!is_string($task)) {
				$this->loadController($fs_path, $path);
				return;
			}

			$task = strtolower($task);

			if (is_file($fs_path.'_common.php')) {
				include($fs_path.'_common.php');
			}

			if (is_file($fs_path.$task.'.php')) {
				include($fs_path.$task.'.php');
				return;
			}

			if (is_dir($fs_path.$task)) {
				$this->loadController($fs_path.$task.DS,$path);
				return;
			}

			die('Bad request (code 1003)');
		}

		function route()
		{
			$cfg = Agora::config();
			$path = array();

			$path[] = (isset($_REQUEST['task']) && strlen(trim($_REQUEST['task']))) ? trim($_REQUEST['task']) : $this->_vars['task'];
			$path[] = (isset($_REQUEST['page']) && strlen(trim($_REQUEST['page']))) ? trim($_REQUEST['page']) : $this->_vars['page'];
			$path[] = (isset($_REQUEST['action']) && strlen(trim($_REQUEST['action']))) ? trim($_REQUEST['action']) : $this->_vars['action'];
			if (1 == @$cfg['router_slugs']) {
				$path[] = (array_key_exists('id', $_REQUEST) && strlen(trim(@$_REQUEST['id']))) ? trim(@$_REQUEST['id']) : @$this->_vars['id'];
			}


			foreach ($path as $key => $item) {
				if (is_null($item) || empty($item) || is_numeric($item) || self::isSlug($item)) {
					continue;
				}

				if (!preg_match('/^[\w]+[\w_\d]+$/',$item)) {
					die('Bad request (code 1001 - Go away)');
				}
			}

			$full_path = $path;

			$this->loadController(AGORA_CURRENT_PATH.'controller'.DS,$path);

			if (!class_exists('TaskController')) {
				die('Bad request (code 1004 - TaskController not found)');
			}

			$controller = new TaskController();

			while (count($path) > 0) {
				$method = array_shift($path);
				if (is_string($method)) break;
			}

			if (!isset($method) || !is_string($method)) {
				$method = 'index';
			}

			if (is_string($method) && method_exists($controller,$method)) {
				$controller->$method();
			} elseif (Agora::isPost() && method_exists($controller,'_save')) {
				$controller->_save();
			} elseif (method_exists($controller,'_default')) {
				$controller->_default();
			}

			if (method_exists($controller,'_execute')) {
				$controller->_execute($method);
			}

		}
		
		public function isSlug($string) {
			return preg_match(self::$slugRegex, $string);
		}
		
		public function getIdFromSlug($slug) {
			return intval(preg_replace(self::$slugRegex, '\1', $slug));
		}
	}
	
	function agoraBuildRoute( & $query )
	{
		static $items;
		static $slugs;
		
		$cfg = Agora::config();
		$segments = array();
		$task = false;
		
		if (empty($slugs)) $slugs = array();

		if (!$items) {
			$component	= &JComponentHelper::getComponent('com_agora');
			$menu		= &JSite::getMenu();
			$items		= $menu->getItems('componentid', $component->id);
		}
	
		if (is_array($items)) {
			$query['Itemid'] = $items[0]->id;
		}
		
		$task = 'category';
		if (isset($query['task'])) {
			$segments[] = $task = $query['task'];
			unset($query['task']);
		} elseif (isset($query['action']) || isset($query['page'])) {
			$task = false;
			$segments[] = 'index';
		}

		if (isset($query['page'])) {
			$segments[] = $query['page'];
			unset($query['page']);
		}

		if (isset($query['action'])) {
			$segments[] = $query['action'];
			unset($query['action']);
			// we need this unset for slugs
			$task = false;
		}

		if (1 == $cfg['router_slugs'] && isset($query['id'])) {
			// forget segments already assigned - we're gonna blow em away & do our own thing now :)
			$db = JFactory::getDbo();
			switch ($task) {
				case 'topic':
					// we need 6 pieces of data: id & title for category/forum/topic
					if (!isset($slugs['topic' . $query['id']])) {
						$db->setQuery('SELECT t.id AS topic_id, t.subject AS topic_name, t.forum_id, f.forum_name, f.cat_id, c.cat_name FROM #__agora_topics AS t LEFT JOIN #__agora_forums AS f ON t.forum_id = f.id LEFT JOIN #__agora_categories AS c ON f.cat_id = c.id WHERE t.id = ' . intval($query['id']));
						$data = $db->loadObject();
						$slugs['topic' . $query['id']] = array(
							JFilterOutput::stringURLSafe($data->cat_id . '-' . $data->cat_name),
							JFilterOutput::stringURLSafe($data->forum_id . '-' . $data->forum_name),
							JFilterOutput::stringURLSafe($query['id'] . '-' . $data->topic_name)
						);
					}
					$segments = array_values((array) $slugs['topic' . $query['id']]);
					break;
				case 'forum':
					// we need 4 pieces of data: id & title for category/forum
					if (!isset($slugs['forum' . $query['id']])) {
						$db->setQuery('SELECT f.id AS forum_id, f.forum_name, f.cat_id, c.cat_name FROM #__agora_forums AS f LEFT JOIN #__agora_categories AS c ON f.cat_id = c.id WHERE f.id = ' . intval($query['id']));
						$data = $db->loadObject();
						$slugs['forum' . $query['id']] = array(
							JFilterOutput::stringURLSafe($data->cat_id . '-' . $data->cat_name),
							JFilterOutput::stringURLSafe($query['id'] . '-' . $data->forum_name)
						);
					}
					$segments = array_values((array) $slugs['forum' . $query['id']]);
					break;
				case 'category':
					if (!isset($slugs['category' . $query['id']])) {
						$db->setQuery('SELECT `cat_name` FROM #__agora_categories WHERE id = ' . intval($query['id']));
						$subj = $db->loadResult();
						if (!empty($subj)) {
							$slugs['category' . $query['id']] = JFilterOutput::stringURLSafe($query['id'] . '-' . $subj);
						} else {
							$slugs['category' . $query['id']] = $query['id'];
						}
					}
					$segments = array($slugs['category' . $query['id']]);
					break;
				default:
					// hey, remember what I said about "blowing away" segments? don't here ;)
					$segments[] = $query['id'];
					break;
			}
			
			unset($query['id']);
		}

/*		header('Content-type: text/plain');
		print_r ($query); print_r($segments);die;*/
		return $segments;
	}

	function agoraParseRoute( $segments ) 
	{
		$cfg = Agora::config();
		$dispatcher = & AgoraDispatcher::getInstance();
		
		// fuck it - just pop the damn id off the end
		$mightBeAnId = false;
		if (1 == $cfg['router_slugs'] && isset($segments[count($segments) - 1])) {
			//echo 'Before Pop:<pre>'.print_r($segments,1).'</pre>';
			if (AgoraDispatcher::isSlug($segments[count($segments) - 1])) {
				$mightBeAnId = array_pop($segments);
				$mightBeAnId = AgoraDispatcher::getIdFromSlug($mightBeAnId);
			}
			//echo 'After Pop:<pre>'.print_r($segments,1).'</pre>';
			// go ahead & check the rest here - looking for these structures:
			// 1-category/1-forum/1-topic.html
			// 1-category/1-forum.html
			// 1-category.html <- this one is done by now ;)
			if (empty($segments) || AgoraDispatcher::isSlug($segments[0])) {
				$tasks = array('index', 'forum', 'topic');
				$dispatcher->setVar('task', $tasks[count($segments)]);
				$dispatcher->setVar('id', $mightBeAnId);
				//echo 'Segments:<pre>'.print_r($segments,1).'</pre>';
				//echo 'Dispatcher:<pre>'.print_r($dispatcher,1).'</pre>';
				return array();
			}
		}

		if (count($segments) > 0) {
			$dispatcher->setVar('task',$segments[0]);
		}

		// task/action
		if (count($segments) == 2) {
			if (isset($_REQUEST['page']) && strlen(trim($_REQUEST['page']))) {
				$dispatcher->setVar('action',$segments[1]);
			} else {
				$dispatcher->setVar('page',$segments[1]);
			}
//			$dispatcher->setVar('page',$segments[1]);
//			$vars['action'] = $segments[1];
		}

		// task/page/action
		if (count($segments) > 2) {
			$dispatcher->setVar('page',$segments[1]);
			$dispatcher->setVar('action',$segments[2]);
//			$vars['action'] = $segments[2];
		}
		
		if ($mightBeAnId) {
			$dispatcher->setVar('id', $mightBeAnId);
		}

		return array();
	}
